package com.xdhl.fu.member.service.impl;

import com.xdhl.fu.common.core.constant.CacheConstants;
import com.xdhl.fu.common.core.constant.SecurityConstants;
import com.xdhl.fu.common.core.utils.JwtUtils;
import com.xdhl.fu.common.core.utils.ServletUtils;
import com.xdhl.fu.common.core.utils.ip.IpUtils;
import com.xdhl.fu.common.core.utils.uuid.IdUtils;
import com.xdhl.fu.common.redis.service.RedisService;
import com.xdhl.fu.member.domain.vo.MemberBasicVO;
import com.xdhl.fu.member.service.IMemberTokenService;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 会员token业务实现
 *
 * @author 朱力维
 * @time 2022/6/6 12:38
 */
@Component
public class MemberTokenServiceImpl implements IMemberTokenService {
    @Resource
    private RedisService redisService;

    protected static final long MILLIS_SECOND = 1000;

    protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;

    private final static long expireTime = CacheConstants.EXPIRATION;

    private final static String ACCESS_TOKEN = CacheConstants.LOGIN_TOKEN_KEY;

    private final static String version = CacheConstants.VERSION;

    /**
     * 创建token
     *
     * @param member
     * @param username
     * @return token令牌 token有限期 版本信息
     */
    public Map<String, Object> createToken(MemberBasicVO member, String username) {
        member.setIpaddr(IpUtils.getIpAddr(ServletUtils.getRequest()));
        String token = IdUtils.fastUUID();
        member.setToken(token);
        // 刷新token
        refreshToken(member);
        // Jwt存储信息
        Map<String, Object> claimsMap = new HashMap<String, Object>();
        claimsMap.put(SecurityConstants.USER_KEY, token);
        claimsMap.put(SecurityConstants.DETAILS_USER_ID, member.getDataId());
        claimsMap.put(SecurityConstants.DETAILS_USERNAME, username);

        // 接口返回信息
        Map<String, Object> rspMap = new HashMap<String, Object>();
        rspMap.put("access_token", JwtUtils.createToken(claimsMap));
        rspMap.put("expires_in", expireTime);
        rspMap.put("version", version);
        return rspMap;
    }

    /**
     * 刷新令牌有效期
     *
     * @param loginMember 登录信息
     */
    public void refreshToken(MemberBasicVO loginMember) {
        loginMember.setLoginTime(System.currentTimeMillis());
        loginMember.setExpireTime(loginMember.getLoginTime() + expireTime * MILLIS_MINUTE);
        // 根据uuid将loginMember缓存
        String userKey = getTokenKey(loginMember.getToken());
        redisService.setCacheObject(userKey, loginMember, expireTime, TimeUnit.MINUTES);
    }

    private String getTokenKey(String token) {
        return ACCESS_TOKEN + token;
    }
}
